package com.jboost.modules.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Joiner;
import com.jboost.common.api.dto.OnlineAuthDTO;
import com.jboost.common.api.dto.message.*;
import com.jboost.common.aspect.UrlMatchEnum;
import com.jboost.common.config.CommonConfig;
import com.jboost.common.constant.CacheConstant;
import com.jboost.common.constant.CommonConstant;
import com.jboost.common.constant.DataBaseConstant;
import com.jboost.common.constant.WebsocketConst;
import com.jboost.common.domain.DomainConstant;
import com.jboost.common.exception.JBoostException;
import com.jboost.common.file.FileCommonVo;
import com.jboost.common.file.JboostFileVo;
import com.jboost.common.system.api.ISysBaseAPI;
import com.jboost.common.system.query.QueryGenerator;
import com.jboost.common.system.vo.*;
import com.jboost.common.util.*;
import com.jboost.config.mybatis.DomainContext;
import com.jboost.modules.file.entity.JboostFile;
import com.jboost.modules.file.service.IJboostFileService;
import com.jboost.modules.message.entity.SysMessageTemplate;
import com.jboost.modules.message.handle.impl.EmailSendMsgHandle;
import com.jboost.modules.message.service.ISysMessageTemplateService;
import com.jboost.modules.message.websocket.WebSocket;
import com.jboost.modules.system.entity.*;
import com.jboost.modules.system.mapper.*;
import com.jboost.modules.system.service.*;
import com.jboost.modules.system.util.SecurityUtil;
import com.jboost.modules.system.vo.SysUserAccountVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 底层共通业务API，提供其他独立模块调用
 * @Author: scott
 * @Date:2019-4-20
 * @Version:V1.0
 */
@Slf4j
@Service
public class SysBaseApiImpl implements ISysBaseAPI {
	/** 当前系统数据库类型 */
	private static String DB_TYPE = "";
	@Autowired
	private ISysMessageTemplateService sysMessageTemplateService;
	@Resource
	private SysLogMapper sysLogMapper;
	@Resource
	private SysUserMapper userMapper;
	@Resource
	private SysAccountMapper accountMapper;
	@Autowired
	private ISysUserAccountService iSysUserAccountService;
	@Autowired
	private ISysRoleService iSysRoleService;
	@Autowired
	private ISysRolePermissionService sysRolePermissionService;
	@Autowired
	private ISysUserService iSysUserService;
	@Autowired
	private ISysAccountService iSysAccountService;
	@Resource
	private SysUserRoleMapper sysUserRoleMapper;
	@Autowired
	private ISysDepartService sysDepartService;
	@Autowired
	private ISysDictService sysDictService;
	@Autowired
	private ISysUserDepartService sysUserDepartService;
	@Autowired
	private ISysUserRoleService iSysUserRoleService;
	@Resource
	private SysAnnouncementMapper sysAnnouncementMapper;
	@Resource
	private SysAnnouncementSendMapper sysAnnouncementSendMapper;
	@Resource
    private WebSocket webSocket;
	@Resource
	private SysRoleMapper roleMapper;
	@Resource
	private SysDepartMapper departMapper;
	@Resource
	private SysCategoryMapper sysCategoryMapper;

	@Autowired
	private ISysDataSourceService dataSourceService;
	@Resource
	private SysPermissionMapper sysPermissionMapper;
	@Autowired
	private ISysPermissionDataRuleService sysPermissionDataRuleService;
	@Autowired
	private ISysDataLogService dataLogService;
	@Autowired
	private IJboostFileService fileService;
	@Autowired
	private ISysTenantService tenantService;

	@Override
	public void addDataLog(String tableName, String dataId, String dataContent) {
		dataLogService.addDataLog(tableName, dataId, dataContent);
	}

	@Override
	@Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username", unless = "#result == null")
	public LoginUser getUserByName(String username) {
		if(oConvertUtils.isEmpty(username)) {
			return null;
		}
		LoginUser loginUser = new LoginUser();
		SysUser sysUser = userMapper.getUserByNameOrId(username);
		//如果找不到用户尝试用手机找一下
		if(sysUser == null ){
			sysUser = userMapper.getUserByPhone(username);
		}
		if(sysUser==null) {
			return null;
		}
		BeanUtils.copyProperties(sysUser, loginUser);
		return loginUser;
	}
	@Override
	public LoginUser getAccountByName(String accountName) {
		if(oConvertUtils.isEmpty(accountName)) {
			return null;
		}
		LoginUser loginUser = new LoginUser();
		SysAccount sysAccount = accountMapper.getAccountByNameAndDomain(accountName,accountName, DomainContext.getDomain());
		if(sysAccount==null) {
			return null;
		}
		BeanUtils.copyProperties(sysAccount, loginUser);
		return loginUser;
	}

	@Override
	public String translateDictFromTable(String table, String text, String code, String key) {
		return sysDictService.queryTableDictTextByKey(table, text, code, key);
	}

	@Override
	public String translateDict(String code, String key) {
		return sysDictService.queryDictTextByKey(code, key);
	}

	@Override
	public List<SysPermissionDataRuleModel> queryPermissionDataRule(String component, String requestPath, String username) {
		List<SysPermission> currentSyspermission = null;
		if(oConvertUtils.isNotEmpty(component)) {
			//1.通过注解属性pageComponent 获取菜单
			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
			query.eq(SysPermission::getDelFlag,0);
			query.eq(SysPermission::getComponent, component);
			currentSyspermission = sysPermissionMapper.selectList(query);
		}else {
			//1.直接通过前端请求地址查询菜单
			LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
			query.eq(SysPermission::getMenuType,2);
			query.eq(SysPermission::getDelFlag,0);
			query.eq(SysPermission::getUrl, requestPath);
			currentSyspermission = sysPermissionMapper.selectList(query);
			//2.未找到 再通过自定义匹配URL 获取菜单
			if(currentSyspermission==null || currentSyspermission.size()==0) {
				//通过自定义URL匹配规则 获取菜单（实现通过菜单配置数据权限规则，实际上针对获取数据接口进行数据规则控制）
				String userMatchUrl = UrlMatchEnum.getMatchResultByUrl(requestPath);
				LambdaQueryWrapper<SysPermission> queryQserMatch = new LambdaQueryWrapper<SysPermission>();
				queryQserMatch.eq(SysPermission::getMenuType, 1);
				queryQserMatch.eq(SysPermission::getDelFlag, 0);
				queryQserMatch.eq(SysPermission::getUrl, userMatchUrl);
				if(oConvertUtils.isNotEmpty(userMatchUrl)){
					currentSyspermission = sysPermissionMapper.selectList(queryQserMatch);
				}
			}
			//3.未找到 再通过正则匹配获取菜单
			if(currentSyspermission==null || currentSyspermission.size()==0) {
				//通过正则匹配权限配置
				String regUrl = getRegexpUrl(requestPath);
				if(regUrl!=null) {
					currentSyspermission = sysPermissionMapper.selectList(new LambdaQueryWrapper<SysPermission>().eq(SysPermission::getMenuType,2).eq(SysPermission::getUrl, regUrl).eq(SysPermission::getDelFlag,0));
				}
			}
		}
		if(currentSyspermission!=null && currentSyspermission.size()>0){
			List<SysPermissionDataRuleModel> dataRules = new ArrayList<SysPermissionDataRuleModel>();
			for (SysPermission sysPermission : currentSyspermission) {
				// update-begin--Author:scott Date:20191119 for：数据权限规则编码不规范，项目存在相同包名和类名 #722
				List<SysPermissionDataRule> temp = sysPermissionDataRuleService.queryPermissionDataRules(username, sysPermission.getId());
				if(temp!=null && temp.size()>0) {
					//dataRules.addAll(temp);
					dataRules = oConvertUtils.entityListToModelList(temp,SysPermissionDataRuleModel.class);
				}
				// update-end--Author:scott Date:20191119 for：数据权限规则编码不规范，项目存在相同包名和类名 #722
			}
			return dataRules;
		}
		return null;
	}

	/**
	 * 匹配前端传过来的地址 匹配成功返回正则地址
	 * AntPathMatcher匹配地址
	 *()* 匹配0个或多个字符
	 *()**匹配0个或多个目录
	 */
	private String getRegexpUrl(String url) {
		List<String> list = sysPermissionMapper.queryPermissionUrlWithStar();
		if(list!=null && list.size()>0) {
			for (String p : list) {
				PathMatcher matcher = new AntPathMatcher();
				if(matcher.match(p, url)) {
					return p;
				}
			}
		}
		return null;
	}

	@Override
	public SysUserCacheInfo getCacheUser(String username) {
		SysUserCacheInfo info = new SysUserCacheInfo();
		info.setOneDepart(true);
		LoginUser user = this.getUserByName(username);
		if(user!=null) {
			info.setSysUserCode(user.getUsername());
			info.setSysUserName(user.getRealname());
			info.setSysOrgCode(user.getOrgCode());
			info.setBusinessId(user.getBusinessId());
		}
		//多部门支持in查询
		List<SysDepart> list = departMapper.queryUserDeparts(user.getId());
		List<String> sysMultiOrgCode = new ArrayList<String>();
		if(list==null || list.size()==0) {
			//当前用户无部门
			//sysMultiOrgCode.add("0");
		}else if(list.size()==1) {
			sysMultiOrgCode.add(list.get(0).getOrgCode());
		}else {
			info.setOneDepart(false);
			for (SysDepart dpt : list) {
				sysMultiOrgCode.add(dpt.getOrgCode());
			}
		}
		info.setSysMultiOrgCode(sysMultiOrgCode);
		return info;
	}

	@Override
	public LoginUser getUserById(String id) {
		if(oConvertUtils.isEmpty(id)) {
			return null;
		}
		LoginUser loginUser = new LoginUser();
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>().eq(SysUser::getId,id).last(" LIMIT 1");
		SysUser sysUser = userMapper.selectOne(queryWrapper);
		if(sysUser==null) {
			return null;
		}
		BeanUtils.copyProperties(sysUser, loginUser);
		loginUser.setRoles(sysUserRoleMapper.getRoleByUserName(loginUser.getUsername()));
		loginUser.setSingleRoles(sysUserRoleMapper.getRoleByUserId(loginUser.getId(),null));
		return loginUser;
	}

	@Override
	public List<LoginUser> getUserByIds(List<String> ids) {
		if( ids==null || ids.size() == 0 ) {
			return null;
		}

		List<SysUser> sysUserList = userMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getId,ids).orderByDesc(SysUser::getId));
		if(sysUserList==null) {
			return null;
		}

		return sysUserList.stream().map(sysUser->{
			LoginUser loginUser = new LoginUser();
			BeanUtils.copyProperties(sysUser, loginUser);
			List<String> roles = sysUserRoleMapper.getRoleByUserId(sysUser.getId(),null);
			loginUser.setRoles(roles);
			return loginUser;
		}).collect(Collectors.toList());
	}

	@Override
	public List<LoginUser> getUserByUserNames(List<String> userNameList) {
		List<SysUser> sysUserList = userMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getUsername,userNameList).orderByDesc(SysUser::getId));
		if(sysUserList==null) {
			return null;
		}
		return sysUserList.stream().map(sysUser-> {
			LoginUser loginUser = new LoginUser();
			BeanUtils.copyProperties(sysUser, loginUser);
			return loginUser;
		}).collect(Collectors.toList());
	}

	@Override
	public List<SysUserVo> getAllUser(String domain) {
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>().eq(SysUser::getDelFlag,CommonConstant.DEL_FLAG_0).eq(SysUser::getStatus,CommonConstant.USER_UNFREEZE);
//		if(StringUtils.isNotEmpty(domain)){
//			queryWrapper.eq(SysUser::getDomain,domain);
//		}
		List<SysUser> userList = userMapper.selectList(queryWrapper);
		List<String> userIds = userList.stream().map(SysUser::getId).collect(Collectors.toList());
		List<SysUserRole> sysUserRoleList = sysUserRoleMapper.selectList(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId,userIds));

		return userList.stream().map(u->{
			SysUserVo userVo = new SysUserVo();
			BeanUtils.copyProperties(u,userVo);
			List<String> roleIds = sysUserRoleList.stream().filter(r->r.getUserId().equals(u.getId())).map(SysUserRole::getRoleId).collect(Collectors.toList());
			userVo.setRoleIds(roleIds);
			return userVo;
		}).collect(Collectors.toList());
	}

	@Override
	public List<String> getRolesByUsername(String username) {
		return sysUserRoleMapper.getRoleByUserName(username);
	}

	@Override
	public List<String> getDepartIdsByUsername(String username) {
		List<SysDepart> list = sysDepartService.queryDepartsByUsername(username);
		List<String> result = new ArrayList<>(list.size());
		for (SysDepart depart : list) {
			result.add(depart.getId());
		}
		return result;
	}

	@Override
	public List<String> getDepartNamesByUsername(String username) {
		List<SysDepart> list = sysDepartService.queryDepartsByUsername(username);
		List<String> result = new ArrayList<>(list.size());
		for (SysDepart depart : list) {
			result.add(depart.getDepartName());
		}
		return result;
	}

	@Override
	public DictModel getParentDepartId(String departId) {
		SysDepart depart = departMapper.getParentDepartId(departId);
		DictModel model = new DictModel(depart.getId(),depart.getParentId());
		return model;
	}

	@Override
	@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code")
	public List<DictModel> queryDictItemsByCode(String code) {
		return sysDictService.queryDictItemsByCode(code);
	}

	@Override
	public DictModel queryDictItemsByCodeAndItemValue(String code,String itemValue) {
		List<DictModel> modelList = this.queryDictItemsByCode(code);
		if(modelList==null)
			return null;
		return modelList.stream().filter(model->model.getValue().equals(itemValue)).findFirst().orElse(null);
	}

	@Override
	public List<DictModel> queryTableDictItemsByCode(String table, String text, String code) {
		//update-begin-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑，想法不错 LOWCOD-799
		if(table.indexOf("#{")>=0){
			table = QueryGenerator.getSqlRuleValue(table);
		}
		//update-end-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑，想法不错 LOWCOD-799
		return sysDictService.queryTableDictItemsByCode(table, text, code);
	}

	@Override
	public List<DictModel> queryAllDepartBackDictModel() {
		return sysDictService.queryAllDepartBackDictModel();
	}

	@Override
	public void sendSysAnnouncement(MessageDTO message) {
		this.sendSysAnnouncement(message.getFromUser(),
				message.getToUser(),
				message.getTitle(),
				message.getContent(),
				message.getCategory());
	}

	@Override
	public void sendBusAnnouncement(BusMessageDTO message) {
		sendBusAnnouncement(message.getFromUser(),
				message.getToUser(),
				message.getTitle(),
				message.getContent(),
				message.getCategory(),
				message.getBusType(),
				message.getBusId());
	}

	@Override
	public void sendTemplateAnnouncement(TemplateMessageDTO message) {
		String templateCode = message.getTemplateCode();
		String title = message.getTitle();
		Map<String,String> map = message.getTemplateParam();
		String fromUser = message.getFromUser();
		String toUser = message.getToUser();

		List<SysMessageTemplate> sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode);
		if(sysSmsTemplates==null||sysSmsTemplates.size()==0){
			throw new JBoostException("消息模板不存在，模板编码："+templateCode);
		}
		SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0);
		//模板标题
		title = title==null?sysSmsTemplate.getTemplateName():title;
		//模板内容
		String content = sysSmsTemplate.getTemplateContent();
		if(map!=null) {
			for (Map.Entry<String, String> entry : map.entrySet()) {
				String str = "${" + entry.getKey() + "}";
				if(oConvertUtils.isNotEmpty(title)){
					title = title.replace(str, entry.getValue());
				}
				content = content.replace(str, entry.getValue());
			}
		}

		SysAnnouncement announcement = new SysAnnouncement();
		announcement.setTitile(title);
		announcement.setMsgContent(content);
		announcement.setSender(fromUser);
		announcement.setPriority(CommonConstant.PRIORITY_M);
		announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
		announcement.setSendStatus(CommonConstant.HAS_SEND);
		announcement.setSendTime(new Date());
		announcement.setMsgCategory(CommonConstant.MSG_CATEGORY_2);
		announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
		sysAnnouncementMapper.insert(announcement);
		// 2.插入用户通告阅读标记表记录
		String userId = toUser;
		String[] userIds = userId.split(",");
		String anntId = announcement.getId();
		for(int i=0;i<userIds.length;i++) {
			if(oConvertUtils.isNotEmpty(userIds[i])) {
				SysUser sysUser = userMapper.getUserByNameOrId(userIds[i]);
				if(sysUser==null) {
					continue;
				}
				SysAnnouncementSend announcementSend = new SysAnnouncementSend();
				announcementSend.setAnntId(anntId);
				announcementSend.setUserId(sysUser.getId());
				announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
				sysAnnouncementSendMapper.insert(announcementSend);
				JSONObject obj = new JSONObject();
				obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
				obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
				obj.put(WebsocketConst.MSG_ID, announcement.getId());
				obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
				webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
			}
		}

	}

	@Override
	public void sendBusTemplateAnnouncement(BusTemplateMessageDTO message) {
		String templateCode = message.getTemplateCode();
		String title = message.getTitle();
		Map<String,String> map = message.getTemplateParam();
		String fromUser = message.getFromUser();
		String toUser = message.getToUser();
		String busId = message.getBusId();
		String busType = message.getBusType();

		List<SysMessageTemplate> sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode);
		if(sysSmsTemplates==null||sysSmsTemplates.size()==0){
			throw new JBoostException("消息模板不存在，模板编码："+templateCode);
		}
		SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0);
		//模板标题
		title = title==null?sysSmsTemplate.getTemplateName():title;
		//模板内容
		String content = sysSmsTemplate.getTemplateContent();
		if(map!=null) {
			for (Map.Entry<String, String> entry : map.entrySet()) {
				String str = "${" + entry.getKey() + "}";
				title = title.replace(str, entry.getValue());
				content = content.replace(str, entry.getValue());
			}
		}
		SysAnnouncement announcement = new SysAnnouncement();
		announcement.setTitile(title);
		announcement.setMsgContent(content);
		announcement.setSender(fromUser);
		announcement.setPriority(CommonConstant.PRIORITY_M);
		announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
		announcement.setSendStatus(CommonConstant.HAS_SEND);
		announcement.setSendTime(new Date());
		announcement.setMsgCategory(CommonConstant.MSG_CATEGORY_2);
		announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
		announcement.setBusId(busId);
		announcement.setBusType(busType);
		announcement.setOpenType(SysAnnmentTypeEnum.getByType(busType).getOpenType());
		announcement.setOpenPage(SysAnnmentTypeEnum.getByType(busType).getOpenPage());
		sysAnnouncementMapper.insert(announcement);
		// 2.插入用户通告阅读标记表记录
		String userId = toUser;
		String[] userIds = userId.split(",");
		String anntId = announcement.getId();
		for(int i=0;i<userIds.length;i++) {
			if(oConvertUtils.isNotEmpty(userIds[i])) {
				SysUser sysUser = userMapper.getUserByNameOrId(userIds[i]);
				if(sysUser==null) {
					continue;
				}
				SysAnnouncementSend announcementSend = new SysAnnouncementSend();
				announcementSend.setAnntId(anntId);
				announcementSend.setUserId(sysUser.getId());
				announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
				sysAnnouncementSendMapper.insert(announcementSend);
				JSONObject obj = new JSONObject();
				obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
				obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
				obj.put(WebsocketConst.MSG_ID, announcement.getId());
				obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
				webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
			}
		}
	}

	@Override
	public String parseTemplateByCode(TemplateDTO templateDTO) {
		String templateCode = templateDTO.getTemplateCode();
		Map<String, String> map = templateDTO.getTemplateParam();
		List<SysMessageTemplate> sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode);
		if(sysSmsTemplates==null||sysSmsTemplates.size()==0){
			throw new JBoostException("消息模板不存在，模板编码："+templateCode);
		}
		SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0);
		//模板内容
		String content = sysSmsTemplate.getTemplateContent();
		if(map!=null) {
			for (Map.Entry<String, String> entry : map.entrySet()) {
				String str = "${" + entry.getKey() + "}";
				content = content.replace(str, entry.getValue());
			}
		}
		return content;
	}

	@Override
	public void updateSysAnnounReadFlag(String busType, String busId) {
		SysAnnouncement announcement = sysAnnouncementMapper.selectOne(new QueryWrapper<SysAnnouncement>().eq("bus_type",busType).eq("bus_id",busId));
		if(announcement != null){
			LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
			String userId = sysUser.getId();
			LambdaUpdateWrapper<SysAnnouncementSend> updateWrapper = new UpdateWrapper().lambda();
			updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG);
			updateWrapper.set(SysAnnouncementSend::getReadTime, new Date());
			updateWrapper.last("where annt_id ='"+announcement.getId()+"' and user_id ='"+userId+"'");
			SysAnnouncementSend announcementSend = new SysAnnouncementSend();
			sysAnnouncementSendMapper.update(announcementSend, updateWrapper);
		}
	}

	/**
	 * 获取数据库类型
	 * @param dataSource
	 * @return
	 * @throws SQLException
	 */
	private String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException{
		if("".equals(DB_TYPE)) {
			Connection connection = dataSource.getConnection();
			try {
				DatabaseMetaData md = connection.getMetaData();
				String dbType = md.getDatabaseProductName().toLowerCase();
				if(dbType.indexOf("mysql")>=0) {
					DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL;
				}else if(dbType.indexOf("oracle")>=0) {
					DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE;
				}else if(dbType.indexOf("sqlserver")>=0||dbType.indexOf("sql server")>=0) {
					DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER;
				}else if(dbType.indexOf("postgresql")>=0) {
					DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL;
				}else {
					throw new JBoostException("数据库类型:["+dbType+"]不识别!");
				}
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}finally {
				connection.close();
			}
		}
		return DB_TYPE;

	}

	@Override
	public List<DictModel> queryAllDict() {
		// 查询并排序
		QueryWrapper<SysDict> queryWrapper = new QueryWrapper<SysDict>();
		queryWrapper.orderByAsc("create_time");
		List<SysDict> dicts = sysDictService.list(queryWrapper);
		// 封装成 model
		List<DictModel> list = new ArrayList<DictModel>();
		for (SysDict dict : dicts) {
			list.add(new DictModel(dict.getDictCode(), dict.getDictName()));
		}

		return list;
	}

	@Override
	public List<SysCategoryModel> queryAllDSysCategory() {
		List<SysCategory> ls = sysCategoryMapper.selectList(null);
		List<SysCategoryModel> res = oConvertUtils.entityListToModelList(ls,SysCategoryModel.class);
		return res;
	}

	@Override
	public List<DictModel> queryFilterTableDictInfo(String table, String text, String code, String filterSql) {
		return sysDictService.queryTableDictItemsByCodeAndFilter(table,text,code,filterSql);
	}

	@Override
	public List<String> queryTableDictByKeys(String table, String text, String code, String[] keyArray) {
		return sysDictService.queryTableDictByKeys(table,text,code,Joiner.on(",").join(keyArray));
	}

	@Override
	public List<ComboModel> queryAllUserBackCombo() {
		List<ComboModel> list = new ArrayList<ComboModel>();
		List<SysUser> userList = userMapper.selectList(new QueryWrapper<SysUser>().eq("status",1).eq("del_flag",0));
		for(SysUser user : userList){
			ComboModel model = new ComboModel();
			model.setTitle(user.getRealname());
			model.setId(user.getId());
			model.setUsername(user.getUsername());
			list.add(model);
		}
		return list;
	}

	@Override
	public JSONObject queryAllUser(String userIds, Integer pageNo, Integer pageSize) {
		JSONObject json = new JSONObject();
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().eq("status",1).eq("del_flag",0);
		List<ComboModel> list = new ArrayList<ComboModel>();
		Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
		IPage<SysUser> pageList = userMapper.selectPage(page, queryWrapper);
		for(SysUser user : pageList.getRecords()){
			ComboModel model = new ComboModel();
			model.setUsername(user.getUsername());
			model.setTitle(user.getRealname());
			model.setId(user.getId());
			model.setEmail(user.getEmail());
			if(oConvertUtils.isNotEmpty(userIds)){
				String[] temp = userIds.split(",");
				for(int i = 0; i<temp.length;i++){
					if(temp[i].equals(user.getId())){
						model.setChecked(true);
					}
				}
			}
			list.add(model);
		}
		json.put("list",list);
		json.put("total",pageList.getTotal());
		return json;
	}

	@Override
	public List<ComboModel> queryAllRole() {
		List<ComboModel> list = new ArrayList<ComboModel>();
		List<SysRole> roleList = roleMapper.selectList(new LambdaQueryWrapper<SysRole>().ne(SysRole::getId,"1580402267708817410"));
		for(SysRole role : roleList){
			ComboModel model = new ComboModel();
			model.setTitle(role.getRoleName());
			model.setId(role.getId());
			list.add(model);
		}
		return list;
	}

    @Override
    public List<ComboModel> queryAllRole(String[] roleIds) {
        List<ComboModel> list = new ArrayList<ComboModel>();
        List<SysRole> roleList = roleMapper.selectList(new QueryWrapper<SysRole>());
        for(SysRole role : roleList){
            ComboModel model = new ComboModel();
            model.setTitle(role.getRoleName());
            model.setId(role.getId());
            model.setRoleCode(role.getRoleCode());
            if(oConvertUtils.isNotEmpty(roleIds)) {
                for (int i = 0; i < roleIds.length; i++) {
                    if (roleIds[i].equals(role.getId())) {
                        model.setChecked(true);
                    }
                }
            }
            list.add(model);
        }
        return list;
    }

	@Override
	public List<String> getRoleIdsByUsername(String username) {
		return sysUserRoleMapper.getRoleIdByUserName(username);
	}

	@Override
	public String getDepartIdsByOrgCode(String orgCode) {
		return departMapper.queryDepartIdByOrgCode(orgCode);
	}

	@Override
	public List<SysDepartModel> getAllSysDepart() {
		List<SysDepartModel> departModelList = new ArrayList<SysDepartModel>();
		List<SysDepart> departList = departMapper.selectList(new QueryWrapper<SysDepart>().eq("del_flag","0"));
		for(SysDepart depart : departList){
			SysDepartModel model = new SysDepartModel();
			BeanUtils.copyProperties(depart,model);
			departModelList.add(model);
		}
		return departModelList;
	}

	@Override
	public DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId) {
		SysDataSource dbSource = dataSourceService.getById(dbSourceId);
		if(dbSource!=null && StringUtils.isNotBlank(dbSource.getDbPassword())){
			String dbPassword = dbSource.getDbPassword();
			String decodedStr = SecurityUtil.jiemi(dbPassword);
			dbSource.setDbPassword(decodedStr);
		}
		return new DynamicDataSourceModel(dbSource);
	}

	@Override
	public DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode) {
		SysDataSource dbSource = dataSourceService.getOne(new LambdaQueryWrapper<SysDataSource>().eq(SysDataSource::getCode, dbSourceCode));
		if(dbSource!=null && StringUtils.isNotBlank(dbSource.getDbPassword())){
			String dbPassword = dbSource.getDbPassword();
			String decodedStr = SecurityUtil.jiemi(dbPassword);
			dbSource.setDbPassword(decodedStr);
		}
		return new DynamicDataSourceModel(dbSource);
	}

	@Override
	public List<String> getDeptHeadByDepId(String deptId) {
		List<SysUser> userList = userMapper.selectList(new QueryWrapper<SysUser>().like("depart_ids",deptId).eq("status",1).eq("del_flag",0));
		List<String> list = new ArrayList<>();
		for(SysUser user : userList){
			list.add(user.getUsername());
		}
		return list;
	}

	@Override
	public void sendWebSocketMsg(String[] userIds, String cmd,String msg) {
		JSONObject obj = new JSONObject();
		obj.put(WebsocketConst.MSG_CMD, cmd);
		obj.put(WebsocketConst.MSG_TXT, msg);
		webSocket.sendMessage(userIds, obj.toJSONString());
	}

	@Override
	public List<LoginUser> queryAllUserByIds(String[] userIds) {
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().eq("status",1).eq("del_flag",0);
		queryWrapper.in("id",userIds);
		List<LoginUser> loginUsers = new ArrayList<>();
		List<SysUser> sysUsers = userMapper.selectList(queryWrapper);
		for (SysUser user:sysUsers) {
			LoginUser loginUser=new LoginUser();
			BeanUtils.copyProperties(user, loginUser);
			loginUsers.add(loginUser);
		}
		return loginUsers;
	}

	/**
	 * 推送签到人员信息
	 * @param userId
	 */
	@Override
	public void meetingSignWebsocket(String userId) {
		JSONObject obj = new JSONObject();
		obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_SIGN);
		obj.put(WebsocketConst.MSG_USER_ID,userId);
		//TODO 目前全部推送，后面修改
		webSocket.sendMessage(obj.toJSONString());
	}

	@Override
	public List<LoginUser> queryUserByIdsOrNames(String[] str) {
		if (null == str || str.length == 0){
			return new ArrayList<>();
		}
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().eq("del_flag",0);
		queryWrapper.in("username",str).or().in("id",str);
		List<LoginUser> loginUsers = new ArrayList<>();
		List<SysUser> sysUsers = userMapper.selectList(queryWrapper);
		for (SysUser user:sysUsers) {
			LoginUser loginUser=new LoginUser();
			BeanUtils.copyProperties(user, loginUser);
			loginUsers.add(loginUser);
		}
		return loginUsers;
	}

	@Override
	public List<LoginUser> queryUserByNames(String[] userNames) {
		QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>().eq("del_flag",0);
		queryWrapper.in("username",userNames);
		List<LoginUser> loginUsers = new ArrayList<>();
		List<SysUser> sysUsers = userMapper.selectList(queryWrapper);
		for (SysUser user:sysUsers) {
			LoginUser loginUser=new LoginUser();
			BeanUtils.copyProperties(user, loginUser);
			loginUsers.add(loginUser);
		}
		return loginUsers;
	}

	@Override
	public SysDepartModel selectAllById(String id) {
		SysDepart sysDepart = sysDepartService.getById(id);
		SysDepartModel sysDepartModel = new SysDepartModel();
		BeanUtils.copyProperties(sysDepart,sysDepartModel);
		return sysDepartModel;
	}

	@Override
	public List<String> queryDeptUsersByUserId(String userId) {
		List<String> userIds = new ArrayList<>();
		List<SysUserDepart> userDepartList = sysUserDepartService.list(new QueryWrapper<SysUserDepart>().eq("user_id",userId));
		if(userDepartList != null){
			//查找所属公司
			String orgCodes = "";
			for(SysUserDepart userDepart : userDepartList){
				//查询所属公司编码
				SysDepart depart = sysDepartService.getById(userDepart.getDepId());
				int length = YouBianCodeUtil.zhanweiLength;
				String compyOrgCode = "";
				if(depart != null && depart.getOrgCode() != null){
					compyOrgCode = depart.getOrgCode().substring(0,length);
					if(orgCodes.indexOf(compyOrgCode) == -1){
						orgCodes = orgCodes + "," + compyOrgCode;
					}
				}
			}
			if(oConvertUtils.isNotEmpty(orgCodes)){
				orgCodes = orgCodes.substring(1);
				List<String> listIds = departMapper.getSubDepIdsByOrgCodes(orgCodes.split(","));
				List<SysUserDepart> userList = sysUserDepartService.list(new QueryWrapper<SysUserDepart>().in("dep_id",listIds));
				for(SysUserDepart userDepart : userList){
					if(!userIds.contains(userDepart.getUserId())){
						userIds.add(userDepart.getUserId());
					}
				}
			}
		}
		return userIds;
	}

	/**
	 * 查询用户拥有的角色集合
	 * @param username
	 * @return
	 */
	@Override
	public Set<String> getUserRoleSet(String username) {
		// 查询用户拥有的角色集合
		List<String> roles = sysUserRoleMapper.getRoleByUserName(username);
		log.info("-------通过数据库读取用户拥有的角色Rules------username： " + username + ",Roles size: " + (roles == null ? 0 : roles.size()));
		return new HashSet<>(roles);
	}

	@Override
	public List<String> getUserRoles(String userId) {
		// 查询用户拥有的角色集合
		List<String> roles = sysUserRoleMapper.getRoleByUserId(userId,DomainContext.getDomain());
		log.info("-------通过数据库读取用户拥有的角色Rules------userId： " + userId + ",Roles size: " + (roles == null ? 0 : roles.size()));
		return roles;
	}

	/**
	 * 查询用户拥有的权限集合
	 * @param username
	 * @return
	 */
	@Override
	public Set<String> getUserPermissionSet(String username) {
		Set<String> permissionSet = new HashSet<>();
		List<SysPermission> permissionList = sysPermissionMapper.queryByUser(username);
		for (SysPermission po : permissionList) {
//			// TODO URL规则有问题？
//			if (oConvertUtils.isNotEmpty(po.getUrl())) {
//				permissionSet.add(po.getUrl());
//			}
			if (oConvertUtils.isNotEmpty(po.getPerms())) {
				permissionSet.add(po.getPerms());
			}
		}
		log.info("-------通过数据库读取用户拥有的权限Perms------username： "+ username+",Perms size: "+ (permissionSet==null?0:permissionSet.size()) );
		return permissionSet;
	}

	/**
	 * 判断online菜单是否有权限
	 * @param onlineAuthDTO
	 * @return
	 */
	@Override
	public boolean hasOnlineAuth(OnlineAuthDTO onlineAuthDTO) {
		String username = onlineAuthDTO.getUsername();
		List<String> possibleUrl = onlineAuthDTO.getPossibleUrl();
		String onlineFormUrl = onlineAuthDTO.getOnlineFormUrl();
		//查询菜单
		LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
		query.eq(SysPermission::getDelFlag, 0);
		query.in(SysPermission::getUrl, possibleUrl);
		List<SysPermission> permissionList = sysPermissionMapper.selectList(query);
		if (permissionList == null || permissionList.size() == 0) {
			//没有配置菜单 找online表单菜单地址
			SysPermission sysPermission = new SysPermission();
			sysPermission.setUrl(onlineFormUrl);
			int count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
			if(count<=0){
				return false;
			}
		} else {
			//找到菜单了
			boolean has = false;
			for (SysPermission p : permissionList) {
				int count = sysPermissionMapper.queryCountByUsername(username, p);
				has = has || (count>0);
			}
			return has;
		}
		return true;
	}

	/**
	 * 查询用户拥有的角色集合 common api 里面的接口实现
	 * @param username
	 * @return
	 */
	@Override
	public Set<String> queryUserRoles(String username) {
		return getUserRoleSet(username);
	}

	@Override
	public List<SysRoleVo> listRoles(String domain) {
		LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.orderByAsc(SysRole::getCreateTime);
		List<SysRole> roleList = roleMapper.selectList(queryWrapper);
		if (null == roleList||roleList.size() == 0)
			return null;

		return roleList.stream().map(r->{
			SysRoleVo roleVo = new SysRoleVo();
			BeanUtils.copyProperties(r,roleVo);
			return roleVo;
		}).collect(Collectors.toList());
	}

	/**
	 * 查询用户拥有的权限集合 common api 里面的接口实现
	 * @param username
	 * @return
	 */
	@Override
	public Set<String> queryUserAuths(String username) {
		return getUserPermissionSet(username);
	}

	/**
	 * 36根据多个用户账号(逗号分隔)，查询返回多个用户信息
	 * @param usernames
	 * @return
	 */
	@Override
	public List<JSONObject> queryUsersByUsernames(String usernames) {
		LambdaQueryWrapper<SysUser> queryWrapper =  new LambdaQueryWrapper<>();
		queryWrapper.in(SysUser::getUsername,usernames.split(","));
		return JSON.parseArray(JSON.toJSONString(userMapper.selectList(queryWrapper))).toJavaList(JSONObject.class);
	}

	@Override
	public List<JSONObject> queryUsersByIds(String ids) {
		LambdaQueryWrapper<SysUser> queryWrapper =  new LambdaQueryWrapper<>();
		queryWrapper.in(SysUser::getId,ids.split(","));
		return JSON.parseArray(JSON.toJSONString(userMapper.selectList(queryWrapper))).toJavaList(JSONObject.class);
	}
	public List<SysUserVo> queryUsersByRoleCode(String roleCode,String domain) {
		return userMapper.getUserByRoleCode(roleCode, domain,null).stream().map(u->{SysUserVo vo = new SysUserVo();BeanUtils.copyProperties(u,vo);return vo;}).collect(Collectors.toList());
	}


	/**
	 * 37根据多个部门编码(逗号分隔)，查询返回多个部门信息
	 * @param orgCodes
	 * @return
	 */
	@Override
	public List<JSONObject> queryDepartsByOrgcodes(String orgCodes) {
		LambdaQueryWrapper<SysDepart> queryWrapper =  new LambdaQueryWrapper<>();
		queryWrapper.in(SysDepart::getOrgCode,orgCodes.split(","));
		return JSON.parseArray(JSON.toJSONString(sysDepartService.list(queryWrapper))).toJavaList(JSONObject.class);
	}

	@Override
	public List<JSONObject> queryDepartsByIds(String ids) {
		LambdaQueryWrapper<SysDepart> queryWrapper =  new LambdaQueryWrapper<>();
		queryWrapper.in(SysDepart::getId,ids.split(","));
		return JSON.parseArray(JSON.toJSONString(sysDepartService.list(queryWrapper))).toJavaList(JSONObject.class);
	}

	/**
	 * 发消息
	 * @param fromUser
	 * @param toUser
	 * @param title
	 * @param msgContent
	 * @param setMsgCategory
	 */
	private void sendSysAnnouncement(String fromUser, String toUser, String title, String msgContent, String setMsgCategory) {
		SysAnnouncement announcement = new SysAnnouncement();
		announcement.setTitile(title);
		announcement.setMsgContent(msgContent);
		announcement.setSender(fromUser);
		announcement.setPriority(CommonConstant.PRIORITY_M);
		announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
		announcement.setSendStatus(CommonConstant.HAS_SEND);
		announcement.setSendTime(new Date());
		announcement.setMsgCategory(setMsgCategory);
		announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
		sysAnnouncementMapper.insert(announcement);
		// 2.插入用户通告阅读标记表记录
		String userId = toUser;
		String[] userIds = userId.split(",");
		String anntId = announcement.getId();
		for(int i=0;i<userIds.length;i++) {
			if(oConvertUtils.isNotEmpty(userIds[i])) {
				SysUser sysUser = userMapper.getUserByNameOrId(userIds[i]);
				if(sysUser==null) {
					continue;
				}
				SysAnnouncementSend announcementSend = new SysAnnouncementSend();
				announcementSend.setAnntId(anntId);
				announcementSend.setUserId(sysUser.getId());
				announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
				sysAnnouncementSendMapper.insert(announcementSend);
				JSONObject obj = new JSONObject();
				obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
				obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
				obj.put(WebsocketConst.MSG_ID, announcement.getId());
				obj.put(WebsocketConst.MSG_TXT, announcement.getTitile());
				webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
			}
		}

	}

	/**
	 * 发消息 带业务参数
	 * @param fromUser
	 * @param toUser
	 * @param title
	 * @param msgContent
	 * @param setMsgCategory
	 * @param busType
	 * @param busId
	 */
	private void sendBusAnnouncement(String fromUser, String toUser, String title, String msgContent, String setMsgCategory, String busType, String busId) {
		SysAnnouncement announcement = new SysAnnouncement();
		announcement.setTitile(title);
		announcement.setMsgContent(msgContent);
		announcement.setSender(fromUser);
		announcement.setPriority(CommonConstant.PRIORITY_M);
		announcement.setMsgType(CommonConstant.MSG_TYPE_UESR);
		announcement.setSendStatus(CommonConstant.HAS_SEND);
		announcement.setSendTime(new Date());
		announcement.setMsgCategory(setMsgCategory);
		announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
		announcement.setBusId(busId);
		announcement.setBusType(busType);
		if (StrUtil.isNotBlank(busType)) {
			announcement.setOpenType(SysAnnmentTypeEnum.getByType(busType).getOpenType());
			announcement.setOpenPage(SysAnnmentTypeEnum.getByType(busType).getOpenPage());
		}
		sysAnnouncementMapper.insert(announcement);
		// 2.插入用户通告阅读标记表记录
		String userId = toUser;
		String[] userIds = userId.split(",");
		String anntId = announcement.getId();
		for(int i=0;i<userIds.length;i++) {
			if(oConvertUtils.isNotEmpty(userIds[i])) {
				SysUser sysUser = iSysUserService.lambdaQuery()
						.eq(SysUser::getId, userIds[i])
						.orderByDesc(SysUser::getId)
						.one();
				if(sysUser==null) {
					continue;
				}
				SysAnnouncementSend announcementSend = new SysAnnouncementSend();
				announcementSend.setAnntId(anntId);
				announcementSend.setUserId(sysUser.getId());
				announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
				sysAnnouncementSendMapper.insert(announcementSend);
				JSONObject obj = new JSONObject();
				obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
				obj.put(WebsocketConst.UNREAD_NUM, sysAnnouncementSendMapper.selectCount(new LambdaQueryWrapper<SysAnnouncementSend>().eq(SysAnnouncementSend::getUserId,sysUser.getId()).eq(SysAnnouncementSend::getReadFlag,"0")) );
				obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId());
				obj.put(WebsocketConst.MSG_ID, announcement.getId());
				obj.put(WebsocketConst.MSG_TXT, announcement.getMsgContent());
				webSocket.sendMessage(sysUser.getId(), obj.toJSONString());
			}
		}
	}

	/**
	 * 发送邮件消息
	 * @param email
	 * @param title
	 * @param content
	 */
	@Override
	public void sendEmailMsg(String email, String title, String content) {
			EmailSendMsgHandle emailHandle=new EmailSendMsgHandle();
			emailHandle.SendMsg(email, title, content);
	}

	/**
	 * 保存账号
	 * @param sysAccount SysAccount账号对象
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public JSONObject saveAccount(JSONObject sysAccount, DomainConstant domainConstant) {

		// 设置产品域
		DomainContext.setDomain(domainConstant.getCode());

		String domain = DomainContext.getDomain();
		System.out.println("产品域的值为: " + domain);

		SysAccount account = sysAccount.toJavaObject(SysAccount.class);

		/**
		 * 1、合伙人账号赋值并保存
		 */
		// 创建时间
		account.setCreateTime(DateUtil.parse(DateUtil.now()));
		// 盐值
		String salt = oConvertUtils.randomGen(8);
		account.setSalt(salt);
		// 密码
		String psw = RandomUtil.randomString(6);
		String passwordEncode = PasswordUtil.encrypt(account.getAccountName(), psw, salt);
		account.setPassword(passwordEncode);
		// 状态
		account.setStatus(1);
		// 逻辑删除
		account.setDelFlag(CommonConstant.DEL_FLAG_0);
		// 保存账号
		iSysAccountService.save(account);

		/**
		 * 2、添加产品域对应用户
		 */
		SysUser sysUser = new SysUser();
		sysUser.setStatus(1);
		sysUser.setUsername(account.getAccountName());
		sysUser.setPhone(account.getPhone());
		sysUser.setRealname(account.getRealName());
		sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
		// 添加用户并绑定角色
		String roleCode = null;
//		if (domainConstant == DomainConstant.PARTNER) {
//			roleCode = RoleCodeConstant.PARTNER_CODE;
//		} else if (domainConstant == DomainConstant.SUPPLIER) {
//			roleCode = RoleCodeConstant.BRAND_REPORT_MANAGER_CODE;
//		}
		SysRole sysRole = iSysRoleService.lambdaQuery()
				.eq(SysRole::getRoleCode, roleCode)
				.one();
		// 保存用户
		iSysUserService.save(sysUser);
		// 保存用户和角色的关联
		SysUserRole sysUserRole = new SysUserRole();
		sysUserRole.setUserId(sysUser.getId());
		sysUserRole.setRoleId(sysRole.getId());
		iSysUserRoleService.save(sysUserRole);
		//默认部门 TODO null空指针
//		SysDepart initDepart = sysDepartService.getOne(new QueryWrapper<SysDepart>().lambda().eq(SysDepart::getOrgCode, "CC_INIT"));
//		iSysUserService.addUserWithDepart(sysUser, initDepart.getId());

		/**
		 * 3、保存账号和用户关联
		 */
		SysUserAccount sysUserAccount = new SysUserAccount();
		sysUserAccount.setAccountId(account.getId());
		sysUserAccount.setUserId(sysUser.getId());
		iSysUserAccountService.save(sysUserAccount);

		/**
		 * 4、发送短信通知
		 */
		JSONObject msgJson = new JSONObject();
		msgJson.put("accountName", account.getAccountName());
		msgJson.put("password", psw);
//		try {
//			DySmsHelper.sendSms(account.getPhone(), msgJson, DySmsEnum.ACCOUNT_TEMPLATE_CODE);
//		}catch (ClientException e) {
//			log.info("开通账号, 发送短信出现异常, 手机号: {}, 登录账号: {}", account.getPhone(), account.getAccountName());
//		}

		JSONObject result = new JSONObject();
		result.put("id", sysUser.getId());
		result.put("name", sysUser.getUsername());
		return result;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void resetAccountPassword(String userId, DomainConstant domainConstant) {
		DomainContext.setDomain(domainConstant.getCode());
		SysUser sysUser = iSysUserService.getById(userId);
		if (sysUser == null) {
			throw new JBoostException("账号不存在");
		}
//		SysAccount account = iSysAccountService.getAccountByUserId(sysUser.getId());

//		String phone = account.getPhone();
		String phone = sysUser.getPhone();
		// 盐值
		String salt = oConvertUtils.randomGen(8);
		// 密码
		String psw = RandomUtil.randomString(6);
		String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), psw, salt);
		boolean update = iSysUserService.lambdaUpdate()
				.eq(SysUser::getId, sysUser.getId())
				.set(SysUser::getSalt, salt)
				.set(SysUser::getPassword, passwordEncode)
				.update();
		System.out.println("重置密码是否成功: " + update);
		if (Boolean.TRUE == update) {
			JSONObject msgJson = new JSONObject();
			msgJson.put("accountName", sysUser.getUsername());
			msgJson.put("password", psw);
//			try {
//				DySmsHelper.sendSms(phone, msgJson, DySmsEnum.RESET_PASSWORD_TEMPLATE_CODE);
//			}catch (ClientException c) {
//				log.info("重置账号密码, 发送短信出现异常, 手机号: {}, 登录账号: {}", sysUser.getPhone(), sysUser.getUsername());
//			}
		}else {
			throw new JBoostException("重置密码失败");
		}

	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void editAccountStatus(String userId, Integer status, DomainConstant domainConstant) {
		DomainContext.setDomain(domainConstant.getCode());

		SysUser sysUser = iSysUserService.getById(userId);
		if (sysUser == null) {
			throw new JBoostException("账号不存在");
		}

//		SysUser sysUser = iSysAccountService.getUserByAccountIdAndDomain(accountId, domainConstant.getCode());
//		if (sysUser == null) {
//			throw new JBoostException("修改账号状态出现异常");
//		}
		boolean update = iSysUserService.lambdaUpdate()
				.eq(SysUser::getId, sysUser.getId())
				.set(SysUser::getStatus, status)
				.update();
		if (Boolean.FALSE == update) {
			throw new JBoostException("修改账号状态出现异常");
		}
	}

	/**
	 * 删除合伙人用户
	 * @param userId
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void deleteUser(String userId, DomainConstant domainConstant) {
		DomainContext.setDomain(domainConstant.getCode());
		SysUser sysUser = iSysUserService.getById(userId);
		if (sysUser == null) {
			throw new JBoostException("账号不存在");
		}
		System.out.println("user账户: " + sysUser);
//		SysAccount account = iSysAccountService.getAccountByUserId(sysUser.getId());
		// 删除账户与用户的关联表
//		iSysUserAccountService.lambdaUpdate()
//				.eq(SysUserAccount::getUserId, sysUser.getId())
//				.eq(SysUserAccount::getAccountId, account.getId())
//				.remove();

		// 删除用户
		iSysUserService.lambdaUpdate()
				.eq(SysUser::getId, sysUser.getId())
				.remove();

		// TODO  删除产品域关联的角色, 只删当前产品域角色, 还是这个产品域所有角色
		iSysUserRoleService.lambdaUpdate()
				.eq(SysUserRole::getUserId, sysUser.getId())
				.remove();

		// 删除产品域关联的部门
		sysUserDepartService.lambdaUpdate()
				.eq(SysUserDepart::getUserId, sysUser.getId())
				.remove();

		// 如果仅有一个产品域还删除了, 账户表也做删除
//		List<SysUserAccountVo> allDomain = iSysAccountService.getAllUserByAccountId(account.getId());
//		if (CollUtil.isEmpty(allDomain)) {
//			iSysAccountService.lambdaUpdate()
//					.eq(SysAccount::getId, account.getId())
//					.remove();
//		}

	}

	@Override
	public Set<String> verifyCreateAccountParam(JSONObject json, DomainConstant domainConstant) {
		String userName = json.getString("accountName");
		String phone = json.getString("phone");

		if (StrUtil.hasBlank(userName, phone)) {
			throw new JBoostException("用户名或电话不能为空");
		}

		Set<String> sameAccountIds = new HashSet<>();

		// 手机号是否重复
		SysAccount maySameAccountByPhone = iSysAccountService.lambdaQuery()
				.eq(SysAccount::getPhone, phone)
				.one();
		if (maySameAccountByPhone != null) {
			// 说明此手机号已开通对应产品域，抛异常
			List<SysUser> userByAccountId = iSysAccountService.getUserByAccountIdAndDomain(maySameAccountByPhone.getId(), domainConstant.getCode());
			if (CollUtil.isNotEmpty(userByAccountId)) {
				if (DomainConstant.BUSINESS.getCode().equals(domainConstant)) {
					throw new JBoostException("此手机号已被其他商家占用, 请更换手机号。");
				} else {
					throw new JBoostException("此手机号已被占用, 请更换手机号。");
				}
			}
			sameAccountIds.add(maySameAccountByPhone.getId());
		}

		// 登录账号是否重复
		SysAccount maySameAccountByName = iSysAccountService.lambdaQuery()
				.eq(SysAccount::getAccountName, userName)
				.one();
		if (maySameAccountByName != null) {
			List<SysUser> userByAccountId = iSysAccountService.getUserByAccountIdAndDomain(maySameAccountByName.getId(), domainConstant.getCode());
			if (CollUtil.isNotEmpty(userByAccountId)) {
				if (DomainConstant.BUSINESS.getCode().equals(domainConstant)) {
					throw new JBoostException("此登录账号已被其他商家占用, 请更换登录账号。");
				} else {
					throw new JBoostException("此登录账号已被占用, 请更换登录账号。");
				}
			}
			sameAccountIds.add(maySameAccountByName.getId());
		}
		return sameAccountIds;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public JSONObject addDomainByAccountId(String accountId, String realName, DomainConstant domainConstant) {
		// 设置产品域
		DomainContext.setDomain(domainConstant.getCode());

		SysAccount account = iSysAccountService.getById(accountId);
		if (account == null) {
			throw new JBoostException("账户不存在");
		}

		List<SysUser> partnerSysUser = iSysAccountService.getUserByAccountIdAndDomain(accountId, domainConstant.getCode());
		if (CollUtil.isNotEmpty(partnerSysUser)) {
			throw new JBoostException("此账号已经开通了此产品域, 无法重复开通");
		}

		// 将账户状态改为启用
		iSysAccountService.lambdaUpdate()
				.eq(SysAccount::getId, accountId)
				.set(SysAccount::getStatus, 1)
				.update();

		/**
		 * 2、添加产品域对应用户
		 */
		if(StringUtils.isEmpty(realName)){
			realName = account.getRealName();
		}
		SysUser sysUser = new SysUser();
		sysUser.setStatus(1);
		sysUser.setUsername(account.getAccountName());
		sysUser.setPassword(account.getPassword());
		sysUser.setSalt(account.getSalt());
		sysUser.setRealname(realName);
		sysUser.setPhone(account.getPhone());
		sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
		// 添加用户并绑定角色
		String roleCode = null;
//		if (domainConstant == DomainConstant.PARTNER) {
//			roleCode = RoleCodeConstant.PARTNER_CODE;
//		} else if (domainConstant == DomainConstant.SUPPLIER) {
//			roleCode = RoleCodeConstant.BRAND_REPORT_MANAGER_CODE;
//		}
		SysRole sysRole = iSysRoleService.lambdaQuery()
				.eq(SysRole::getRoleCode, roleCode)
				.one();
		// 保存用户
		iSysUserService.save(sysUser);
		// 保存用户和角色的关联
		SysUserRole sysUserRole = new SysUserRole();
		sysUserRole.setUserId(sysUser.getId());
		sysUserRole.setRoleId(sysRole.getId());
		iSysUserRoleService.save(sysUserRole);
		//默认部门 TODO null空指针
//		SysDepart initDepart = sysDepartService.getOne(new QueryWrapper<SysDepart>().lambda().eq(SysDepart::getOrgCode, "CC_INIT"));
//		iSysUserService.addUserWithDepart(sysUser, initDepart.getId());

		/**
		 * 3、保存账号和用户关联
		 */
		SysUserAccount sysUserAccount = new SysUserAccount();
		sysUserAccount.setAccountId(account.getId());
		sysUserAccount.setUserId(sysUser.getId());
		iSysUserAccountService.save(sysUserAccount);

		/**
		 * 4、发送短信通知
		 * 已有账号是开通产品域需要发送『产品域账号开通』短信
		 */
		JSONObject msgJson = new JSONObject();
		msgJson.put("accountName", account.getAccountName());
		msgJson.put("domain", domainConstant.getDescription());
//		try {
//			DySmsHelper.sendSms(account.getPhone(), msgJson, DySmsEnum.DOMAIN_OPEN_CODE);
//		}catch (ClientException e) {
//			log.info("开通产品域, 发送短信出现异常, 手机号: {}, 登录账号: {}", account.getPhone(), account.getAccountName());
//		}

		JSONObject resultJson = new JSONObject();
		resultJson.put("userId", sysUser.getId());
		resultJson.put("userName", sysUser.getUsername());
		return resultJson;
	}

	@Override
	public JSONObject getAccountInfoById(String userId, DomainConstant domainConstant) {
		DomainContext.setDomain(domainConstant.getCode());
		System.out.println("code是: " + domainConstant.getCode());
		System.out.println("sysUser的ID是: " + userId);
		SysUser sysUser = iSysUserService.getById(userId);
		if (sysUser == null) {
			throw new JBoostException("账户不存在");
		}
		SysAccount account = iSysAccountService.getAccountByUserId(sysUser.getId());
		// 取得产品域用户的状态和realName
		JSONObject accountJson = new JSONObject();
		accountJson.put("id", account.getId());
		accountJson.put("accountName", account.getAccountName());
		accountJson.put("phone", account.getPhone());
		// TODO 获得哪个用户的真实名称，还是在账户表加字段
//		SysUser sysUser = iSysAccountService.getUserByAccountIdAndDomain(accountId, domainConstant.getCode());
//		accountJson.put("realname", sysUser.getRealname());

		List<SysUserAccountVo> allUser = iSysAccountService.getAllUserByAccountId(account.getId());
		List<String> domainStr = new ArrayList<>();
		if (CollUtil.isNotEmpty(allUser)) {
			for (SysUserAccountVo s : allUser) {
				// 封装对应产品域的状态
				if (domainConstant.getCode().equals(s.getDomain())) {
					accountJson.put("status", s.getStatus());
				}
			}

			List<String> domains = allUser.stream().map(SysUserAccountVo::getDomain).collect(Collectors.toList());
			if (domains.contains(DomainConstant.BUSINESS.getCode())) {
				domainStr.add(DomainConstant.BUSINESS.getDescription());
			}

			if (domains.contains(DomainConstant.OPERATION.getCode())) {
				domainStr.add(DomainConstant.OPERATION.getDescription());
			}


			accountJson.put("domain", domainStr);
		}

		List<String> roleNames = iSysAccountService.getDomainRoleNamesByAccountId(account.getId(), domainConstant.getCode());
		accountJson.put("role", roleNames);
		return accountJson;
	}

	@Override
	public JSONArray getDomainUserByAccountId(String sysAccountId, DomainConstant domainConstant) {
		List<SysUser> user = iSysAccountService.getUserByAccountIdAndDomain(sysAccountId, domainConstant.getCode());
		if (CollUtil.isNotEmpty(user)) {
			return JSONArray.parseArray(JSON.toJSONString(user));
		}
		return null;
	}

	@Override
	public JSONObject getAccountByUserId(String id) {
		SysUserAccount userAccount = iSysUserAccountService.lambdaQuery()
				.eq(SysUserAccount::getUserId, id)
				.eq(SysUserAccount::getDelFlag, 0)
				.one();
		if (userAccount != null) {
			SysAccount account = iSysAccountService.getById(userAccount.getAccountId());
			if (account != null) {
				return (JSONObject) JSON.toJSON(account);
			}
		}
		return null;
	}

	@Override
	public JSONObject getDomainUserById(String sysUserId) {
		SysUser sysUser = iSysUserService.lambdaQuery()
				.eq(SysUser::getId, sysUserId)
				.orderByDesc(SysUser::getId)
				.one();
		return (JSONObject) JSON.toJSON(sysUser);
	}

	@Override
	public String getRealNameByUserName(String userName, DomainConstant domainConstant) {
		DomainContext.setDomain(domainConstant.getCode());
		List<SysUser> userList = iSysUserService.lambdaQuery()
				.eq(SysUser::getUsername, userName)
				.list();
		if (CollUtil.isNotEmpty(userList)) {
			return userList.get(0).getRealname();
		}
		return null;
	}

	@Override
	public List<String> getUserIdsByRoleCode(String roleCode) {
		return iSysUserService.getUserIdsByRoleCode(roleCode);
	}

	@Override
	public FileCommonVo getFileById(String fileId) {
		JboostFile file = fileService.getById(fileId);
		JboostFileVo vo = new JboostFileVo();
		BeanUtil.copyProperties(file,vo);
		return FileUtils.getCommonFile(vo);
	}

	@Override
	public List<FileCommonVo> listFiles(List<String> fileIds) {
		List<JboostFile> file = fileService.listByIds(fileIds);
		if(CollUtil.isEmpty(file)){
			return new ArrayList<>();
		}
		return file.stream().map(f->{
			JboostFileVo vo = new JboostFileVo();
			BeanUtil.copyProperties(f,vo);
			return FileUtils.getCommonFile(vo);
		}).collect(Collectors.toList());
	}

	@Override
	public void updateUserStore(String id, String storeId) {
		iSysUserService.lambdaUpdate().eq(SysUser::getId,id).update();
	}

	@Override
	public void createTenantByStore(String storeId,String storeName) {
		SysTenant tenant = new SysTenant();
		tenant.setBusinessId(storeId);
		tenant.setStatus(CommonConstant.INT_STATUS_1);
		tenant.setBeginDate(new Date());
		tenant.setName(storeName);
		tenant.setPreCode(storeId);
		tenantService.saveStoreTenant(tenant);
	}

	@Override
	public void updateFile(String fileId, String storeId) {
		fileService.updateStoreId(fileId,storeId);
	}

	@Override
	public List<LoginUser> listUserByStoreId(String storeId) {
		List<SysUser> userList = iSysUserService.lambdaQuery().eq(SysUser::getDelFlag,CommonConstant.DEL_FLAG_0).list();
		return userList.stream().map(user->{
			LoginUser loginUser = new LoginUser();
			BeanUtil.copyProperties(user,loginUser);
			return loginUser;
		}).collect(Collectors.toList());
	}

	@Override
	@Transactional
	public void createBusinessUser(String businessId, String phone) {
		SysUser user = new SysUser();
		user.setCreateTime(new Date());// 设置创建时间
		String salt = oConvertUtils.randomGen(8);
		String username = phone;
		String password = RandomUtil.randomString(6);
		if ( "local".equals(CommonConfig.env) || "dev".equals(CommonConfig.env) || "test".equals(CommonConfig.env)){
			password = "123456";
		}
		String passwordEncode = PasswordUtil.encrypt(username, password, salt);
		user.setSalt(salt);
		user.setUsername(username);
		user.setRealname(username);
		user.setPassword(passwordEncode);
//            user.setEmail(email);
		user.setPhone(phone);
		//user.setDomain(DomainConstant.BUSINESS.getCode());
		user.setStatus(CommonConstant.USER_UNFREEZE);
		user.setDelFlag(CommonConstant.DEL_FLAG_0);
		user.setActivitiSync(CommonConstant.ACT_SYNC_0);
		//店铺添加一个管理员角色
		SysRole role = new SysRole();
		role.setRoleCode(businessId+CommonConstant.BUSINESS_ROLE_CODE_SUFFIX);
		role.setRoleName("机构管理员");
		role.setBusinessId(businessId);
		role.setDescription("新增机构时，系统初始化的管理员。");
		role.setIsSystem(1);
		iSysRoleService.save(role);
		//角色只有首页和认证信息的权限
		SysRolePermission index = new SysRolePermission();
		index.setRoleId(role.getId());
		index.setPermissionId("uks53xuod6cv1lgjg1kpwkyoe8odxnnb");
		sysRolePermissionService.save(index);

		SysRolePermission info = new SysRolePermission();
		info.setRoleId(role.getId());
		info.setPermissionId("lnm1ysvm0qxikrvz0mg357sxpx79f69x");
		sysRolePermissionService.save(info);

		iSysUserService.addUserWithRole(user,role.getId());//设置为机构管理员

		/**
		 * 4、发送短信通知
		 */
		JSONObject msgJson = new JSONObject();
		msgJson.put("loginname", user.getUsername());
		msgJson.put("password", password);
		try {
			DySmsHelper.sendSms(user.getPhone(), msgJson, DySmsEnum.BUSINESS_ACCOUNT);
		}catch (ClientException e) {
			log.info("新建机构, 发送短信出现异常, 登录账号: {}，密码: {} ", user.getPhone(), password);
		}
	}

	@Override
	public void updateUserName(String oldPhone, String newPhone) {
		SysUser user = iSysUserService.getUserByName(oldPhone);
		if (null==user){
			return;
		}
		String salt = oConvertUtils.randomGen(8);
		String username = newPhone;
		String password = RandomUtil.randomString(6);
		if ( "local".equals(CommonConfig.env) || "dev".equals(CommonConfig.env) || "test".equals(CommonConfig.env)){
			password = "123456";
		}
		String passwordEncode = PasswordUtil.encrypt(username, password, salt);
		user.setSalt(salt);
		user.setUsername(username);
		user.setPhone(newPhone);
		user.setPassword(passwordEncode);
		iSysUserService.updateById(user);
		/**
		 * 4、发送短信通知
		 */
		JSONObject msgJson = new JSONObject();
		msgJson.put("loginname", user.getUsername());
		msgJson.put("password", password);
		try {
			DySmsHelper.sendSms(user.getPhone(), msgJson, DySmsEnum.BUSINESS_ACCOUNT);
		}catch (ClientException e) {
			log.info("更新机构登录账号, 发送短信出现异常, 登录账号: {}，密码: {} ", user.getPhone(), password);
		}

	}

	@Override
	public JSONObject getBusinessById(String businessId) {
		return iSysUserService.getBusinessById(businessId);
	}

	@Override
	public void businessUseAccountNum(String businessId,String userId) {
		iSysUserService.businessUseAccountNum(businessId,userId,1);
	}

	@Override
	public void businessFreedAccountNum(String businessId, String userId) {
		iSysUserService.businessFreedAccountNum(businessId,userId);
	}

	@Override
	public List<SysUserSimpleVo> listSimpleUserByIds(List<String> userIds) {
		return iSysUserService.listSimpleUserByIds(userIds);
	}
}
